package com.iwat.mail.schedule;

import com.iwat.mail.constant.LogProcessorConstant;
import com.iwat.mail.constant.LogProcessorProperties;
import com.iwat.mail.util.SendMailUtil;
import lombok.AllArgsConstructor;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @author 王伟强
 * @date 2024/2/20 16:00
 */
@Component
@AllArgsConstructor
public class LogProcessor {
    private LogProcessorProperties logProcessorProperties;
    /**
     * 判断日志文件大小，文件超过指定大小则发送邮件通知
     * 每天10点20执行
     */
    @Scheduled(cron = "0 20 10 * * ?")
    public void logFileSizeJudgement() {
        //获取日志文件路径
        String tomcatHome = System.getProperty(LogProcessorConstant.TOMCAT_HOME_SYSTEM_VAR);
        String logPath = tomcatHome + LogProcessorConstant.LOG_PATH;
        String logFilePath = logPath.concat(LogProcessorConstant.FILE_NAME);

        Path source = Paths.get(logFilePath);
        try {
            long sizeInBytes = Files.size(source);
            long sizeInMb = sizeInBytes / (1024 * 1024);
            if (sizeInMb > LogProcessorConstant.FILE_SIZE) {
                //获取项目名称
                String content = "编码中心日志文件" +
                        LogProcessorConstant.LINE_BREAK +
                        logFilePath +
                        LogProcessorConstant.LINE_BREAK +
                        "超过指定大小" +
                        LogProcessorConstant.FILE_SIZE +
                        "MB，系统将在今晚0点进行压缩备份，请注意查看";
                // 发送邮件
                SendMailUtil.sendMail(logProcessorProperties.getEmail(), content);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 处理日志文件，压缩并发送邮件
     * @throws IOException IO异常
     */
    @Scheduled(cron = "0 20 10 * * ?")
    public void processLogFile() throws Exception {
        // 1.获取日志文件路径
        String tomcatHome = System.getProperty(LogProcessorConstant.TOMCAT_HOME_SYSTEM_VAR);
        String logPath = tomcatHome + LogProcessorConstant.LOG_PATH;
        String logFilePath = logPath.concat(LogProcessorConstant.FILE_NAME);

        // 2.检查文件大小，超过512MB才处理
        Path source = Paths.get(logFilePath);
        long sizeInBytes = Files.size(source);
        long sizeInMb = sizeInBytes / (1024 * 1024);
        if (sizeInMb < LogProcessorConstant.FILE_SIZE) {
            System.out.println("源文件效域512MB，不处理。");
            return;
        }

        // 3.生成时间戳
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        String timestamp = now.format(formatter);
        String bakPath = logPath + "catalina_bak_" + timestamp + ".zip";
        Path destination = Paths.get(bakPath);

        // 4.获取源文件行数
        long lineCount;
        try (Stream<String> lines = Files.lines(source)) {
            lineCount = lines.count();
        }

        // 5.压缩并复制文件到目标位置
        try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(destination.toFile()));
             FileInputStream fis = new FileInputStream(source.toFile())) {
            ZipEntry zipEntry = new ZipEntry(source.getFileName().toString());
            zos.putNextEntry(zipEntry);
            byte[] bytes = new byte[1024];
            int length;
            while ((length = fis.read(bytes)) >= 0) {
                zos.write(bytes, 0, length);
            }
            zos.closeEntry();
        }

        // 跳过前面的lineCount行，将剩余行写入源文件
        StringBuilder newLine = new StringBuilder();
        try (Stream<String> lines = Files.lines(source)) {
            lines.skip(lineCount)
                    .forEach(line -> newLine.append(line).append(System.lineSeparator()));
        }
        Files.write(source, newLine.toString().getBytes());

        //发送邮件
        String content = "编码中心日志文件" +
                LogProcessorConstant.LINE_BREAK +
                logFilePath +
                LogProcessorConstant.LINE_BREAK +
                "大小" +
                sizeInMb +
                "MB，压缩备份完成。备份文件路径：" +
                bakPath+
                "，请注意查看。";
        SendMailUtil.sendMail(logProcessorProperties.getEmail(),content);
    }
}
